package cn.wk.service.impl;

import cn.wk.constant.CourseTypeConstant;
import cn.wk.domain.CourseType;
import cn.wk.mapper.CourseTypeMapper;
import cn.wk.service.ICourseTypeService;
import cn.wk.vo.CrumbsVo;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author wk
 * @since 2021-03-06
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    //锁，static修饰 保证是同一把锁
    private static Lock lock = new ReentrantLock();
    @Override
    public List<CourseType> treeData() {
        //去redis中查询
        Object obj = redisTemplate.opsForValue().get(CourseTypeConstant.COURSE_TYPE);
        //判断redis中查询的数据是否为nll
        if(obj != null){
            System.out.println("--------------走了redis-----------------------");
            //强转
            List<CourseType> list = (List<CourseType>)obj;
            return list;
        }else {

            System.out.println("---------------走了数据库---------------------");
            //去数据库中查询
            List<CourseType> resultList = new ArrayList<>();
            if(obj == null){
                try {
                    //上锁
                    lock.lock();
                    if(obj == null){    //双重
                        //数据库查询数据
                        resultList = resultList();
                        redisTemplate.opsForValue().set(CourseTypeConstant
                                .COURSE_TYPE,resultList,new Random()
                                .nextInt(20), TimeUnit.MINUTES);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    //释放锁
                    lock.unlock();
                }
            }
            //添加到redis中

            return resultList;
        }
        //这是sql循环
        //return courseTypeMapper.treeData();
    }

    /**
     * 面包屑
     * @param crouseTypeId
     * @return
     */
    @Override
    public List<CrumbsVo> getCrumbs(Long crouseTypeId) {
        //准备一个list装数据
        ArrayList<CrumbsVo> crumbsVOS = new ArrayList<>();
        //先根据传进来的id去查询出其自身
        CourseType courseType = courseTypeMapper.selectById(crouseTypeId);
        //然后获取其path 这是获取了其族谱
        String path = courseType.getPath();
        //分割
        String[] ids = path.split("\\.");
        //遍历 所有path中的id
        for(String s : ids){
            CrumbsVo crumbsVo = new CrumbsVo();
            //根据id去查询
            CourseType type = courseTypeMapper.selectById(Long.valueOf(s));
            //装自己
            crumbsVo.setOwnerProductType(type);
            //获取了path中所有的pid
            Long pid = type.getPid();
            //这是找出了所有pid相同的
            List<CourseType> courseTypes = courseTypeMapper.selectList(new EntityWrapper<CourseType>().eq("pid", pid));
            //先判断查出来的数据不为null
            if(courseTypes != null){
                //找到所有同级
                Iterator<CourseType> iterator = courseTypes.iterator();
                while (iterator.hasNext()){
                    CourseType next = iterator.next();
                    //判断是否一样 一样将移除自己
                    if(next.getId().longValue() != courseType.getId().longValue()){
                        iterator.remove();
                        break;
                    }
                }
            }
            //添加同级
            crumbsVo.setOtherProductTypes(courseTypes);
            //添加到list集合中
            crumbsVOS.add(crumbsVo);
        }
        return crumbsVOS;
    }

    private List<CourseType> resultList() {
        List<CourseType> list = courseTypeMapper.selectList(null);
        //准备一个新list用来返回
        List<CourseType> result = new ArrayList<>();
        //准备一个map
        HashMap<Long, CourseType> map = new HashMap<>();
        //id 对象
        list.forEach(cType -> {
            map.put(cType.getId(),cType);
        });
        list.forEach(courseType -> {
            Long pid = courseType.getPid();
            if(pid.intValue() == 0){
                result.add(courseType);
            }else{
                //这里是子节点
                //获取父级对象
                CourseType type = map.get(pid);
                type.getChildren().add(courseType);
            }
        });
        return result;
    }

    @Override
    public boolean insert(CourseType entity) {
        redisTemplate.delete(CourseTypeConstant.COURSE_TYPE);
        try {
            TimeUnit.SECONDS.sleep(30L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        redisTemplate.delete(CourseTypeConstant.COURSE_TYPE);
        return super.insert(entity);
    }

    @Override
    public boolean deleteById(Serializable id) {
        redisTemplate.delete(CourseTypeConstant.COURSE_TYPE);
        return super.deleteById(id);
    }
}
